﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Linq;
using Telerik.WinControls;
using Pakxel.Data;
using Pakxel.Framework;
using Telerik.WinControls.UI;
using System.Data.Common;

namespace Pakxel.SmartLogistic.Modulos
{
   public partial class CatEntity : Telerik.WinControls.UI.RadForm
    {
        private delegate bool RuleManager(string CString);
        private Pakxel.Framework.Rules ruleToCheck;
        private RuleManager IsNumeric;
        private MEDataDataContext DataContext;
        private T011 currEntity;
        public CatEntity()
        {
            InitializeComponent();
        }

        internal void ClearControls(Control.ControlCollection Controlsx)
        {
           foreach (var Ctl in Controlsx)
           {
              switch (Ctl.GetType().Name)
              {
                 case "RadDateTimePicker":
                    ((RadDateTimePicker)Ctl).Value = DateTime.Now; break;
                 case "RadSpinEditor":
                    ((RadSpinEditor)Ctl).Value = ((RadSpinEditor)Ctl).Minimum; break;
                 case "RadMultiColumnComboBox":
                    ((RadMultiColumnComboBox)Ctl).SelectedIndex = 0; break;
                 case "RadDropDownList":
                    ((RadDropDownList)Ctl).SelectedIndex = 0; break;
                 case "RadRadioButton":
                    ((RadRadioButton)Ctl).IsChecked = false; break;
                 case "RadTextBox":
                    ((RadTextBox)Ctl).Text = ""; break;
                 case "RadGroupBox": ClearControls(((RadGroupBox)Ctl).Controls); break;

              }
           }
        }
        /// <summary>Des/Habilita los controles marcados para su edicion</summary>
        /// <param name="control">Contenedor</param>
        /// <param name="Enable">Indica si se habilitaran o no</param>
        /// <param name="Clear">Indica si se borrara el contenido de los controles</param>
        private void EnableControls(Control control, bool Enable, bool Clear)
        {
           foreach (Control Ctl in control.Controls)
           {
              switch (Ctl.GetType().Name)
              {
                 case "RadGroupBox":
                    EnableControls(Ctl, Enable, Clear);
                    break;
                 case "RadDateTimePicker":
                    Ctl.Enabled = Enable;
                    break;
                 case "RadMultiColumnComboBox":
                    Ctl.Enabled = Enable;
                    break;
                 case "RadDropDownList":
                    Ctl.Enabled = Enable;
                    break;
                 case "RadRadioButton":
                    Ctl.Enabled = Enable;
                    break;
                 case "RadTextBox":
                    Ctl.Enabled = Enable;
                    ((RadTextBox)Ctl).ReadOnly = !Enable;
                    break;
                 default:
                    break;
              }
              if (Ctl.Controls.Count > 0)
                 EnableControls(Ctl, Enable, Clear);
              else if (Ctl.GetType().Name == "RadGridView")
              {
                 ((RadGridView)Ctl).AllowAddNewRow = Enable;
                 ((RadGridView)Ctl).AllowEditRow = Enable;
                 ((RadGridView)Ctl).AllowDeleteRow = Enable;
              }

           }
        }

        private IEnumerable<T013> getRolesAsignados(T011 EntityRecord)
        {
           IEnumerable<T013> RolesAsignados=null;
           if (EntityRecord != null)
           {
              RolesAsignados = from R in EntityRecord.T013s where R.T011Entity.Equals(EntityRecord.T011Entity) select R;
              RolesAsignado.DataSource = RolesAsignados;
              RolesAsignado.DisplayMember = "T003Rol";
           }
           return RolesAsignados;
        }

        private IQueryable<T003> getRolesDisponibles()
        {
           IQueryable<T003> RolesSinAsignar = from disponibles in DataContext.T003s select disponibles;
           RolesDisponible.DataSource = RolesSinAsignar;
           RolesDisponible.DisplayMember = "T003Rol";
           return RolesSinAsignar;
        }

        private IQueryable<T003> getRolesDisponibles(IEnumerable<T013> RolesAsignados)
        {
           IQueryable<T003> RolesSinAsignar = null;
           if (RolesAsignados != null)
           {
              RolesSinAsignar = from sinasignar in DataContext.T003s
                                                 where
                                                 !(from roles in RolesAsignados select roles.T003Rol).Contains
                                                 (sinasignar.T003Rol)
                                                 select sinasignar;
              RolesDisponible.DataSource = RolesSinAsignar;
              RolesDisponible.DisplayMember = "T003Rol";
           }
           return RolesSinAsignar;
        }
        
        private void ShowEntity(T011 EntityRecord)
        {
           if (EntityRecord != null)
           {
              T011Entity.Text = EntityRecord.T011Entity.ToString();
              T011Nombre.Text = EntityRecord.T011Nombre.ToString();
              T011Domicilio.Text = EntityRecord.T011Domicilio.ToString();
              T011RFC.Text = EntityRecord.T011RFC.ToString();
              DataContext.Log = System.Console.Out;
              T028 T028Record = (EntityRecord.T028s).Where(R => R.T011Entity.Equals(EntityRecord.T011Entity)).SingleOrDefault();
              if (T028Record != null)
              {
                 T028DiasCredito.Text = Convert.ToString(T028Record.T028DiasCredito);
              }

              // Roles Asignados 
              IEnumerable<T013> RolesAsignados = getRolesAsignados(EntityRecord);   

              // Roles Disponibles para Asignar
              getRolesDisponibles(RolesAsignados);
           }
           else
           {
              ClearControls(gpCtesPro.Controls);
              RolesAsignado.DataSource = null;
              RolesDisponible.DataSource = null;
           }
        }

        private void SetupWorkBench()
        {
           
        }

        private void CatEntity_Load(object sender, EventArgs e)
        {
           WorkBenchFilter.TextBox.BackColor = Color.LightYellow;
           DataContext = new MEDataDataContext(WorkBench.ConnectionString);
           FilterSelector.SelectedIndex = 0;
           SetupWorkBench();
           ruleToCheck = new Rules();
           IsNumeric += new RuleManager(ruleToCheck.IsNumeric);
           getRolesDisponibles();
        }

        private void WorkBenchFilter_KeyDown(object sender, KeyEventArgs e)
        {
           if (e.KeyCode == Keys.Enter)
           {
              if (IsNumeric(WorkBenchFilter.Text))
              {
                 var CPEntity = (from CP in DataContext.T011s where CP.T011Entity.Equals(WorkBenchFilter.Text) select CP).SingleOrDefault();
                 if (CPEntity != null)
                 {
                    currEntity = CPEntity;
                    ShowEntity(CPEntity);
                 }
                 else
                 {
                    ClearControls(gpCtesPro.Controls);
                    RolesDisponible.DataSource = null;
                    RolesAsignado.DataSource = null;
                 }
              }
           }
        }

        private void tsbNvo_Click(object sender, EventArgs e)
        {
           currEntity = null;
           EnableControls(gpCtesPro, true, true);
           ClearControls(gpCtesPro.Controls);
           T011Entity.ReadOnly = true;
           RolesAsignado.DataSource = null;
           getRolesDisponibles();
        }

        private void T011Nombre_KeyDown(object sender, KeyEventArgs e)
        {
           if (e.KeyCode == Keys.Enter)
           { 

           }
        }

        private void T011Entity_KeyDown(object sender, KeyEventArgs e)
        {
           if (e.KeyCode == Keys.Enter)
           {

           }
        }

        private void tsbSave_Click(object sender, EventArgs e)
        {
           /// TODO : Validar Campos 
           if (currEntity == null)
           {
              if (DataContext.Connection.State != ConnectionState.Closed)
              {
                 DataContext.Connection.Close();
                 DataContext.Connection.Open();
              }
              else
                 DataContext.Connection.Open();
              using (DbTransaction transaction = DataContext.Connection.BeginTransaction(IsolationLevel.Serializable))
              {
                 DataContext.Transaction = transaction;
                 try
                 {
                    if (!string.IsNullOrEmpty(T011Nombre.Text) && !string.IsNullOrWhiteSpace(T011Nombre.Text))
                    {
                       T014 Parametros = (from P in DataContext.T014s where P.T014IdParametro.Equals("FOLENTITY") select P).SingleOrDefault();
                       Parametros.T014Val1 = (Convert.ToInt32(Parametros.T014Val1) + 1).ToString();
                       T011 newRecord = new T011();
                       T011Entity.Text = Parametros.T014Val1;
                       newRecord.T011Entity = Convert.ToInt32(Parametros.T014Val1);
                       newRecord.T011Nombre = T011Nombre.Text;
                       newRecord.T011Domicilio = T011Domicilio.Text;
                       newRecord.T011RFC = T011RFC.Text;
                       T028 T028Record = new T028();
                       T028Record.T028DiasCredito = Convert.ToInt32(T028DiasCredito.Text);
                       newRecord.T028s.Add(T028Record);
                       DataContext.T011s.InsertOnSubmit(newRecord);
                       DataContext.SubmitChanges();
                       transaction.Commit();
                    }
                 }
                 catch (System.Data.Linq.ChangeConflictException cce)
                 {
                    MessageBox.Show("Error");
                    MainApp.WriteExceptionToLog(cce);
                    transaction.Rollback();
                 }
                 catch (SystemException se)
                 {
                    MainApp.WriteExceptionToLog(se);
                    transaction.Rollback();
                 }
                 finally
                 {
                    DataContext.Connection.Close();
                 }
                 //EnableControls(gpCtesPro, false, false);
              }
           }
           // Se esta editando el registro actual
           else
           {
              try
              {
                 currEntity.T011Nombre = T011Nombre.Text;
                 currEntity.T011Domicilio = T011Domicilio.Text;
                 currEntity.T011RFC = T011RFC.Text;
                 T028 T028Record = (from dc in currEntity.T028s where dc.T011Entity.Equals(currEntity.T011Entity) select dc).SingleOrDefault();
                 T028Record.T028DiasCredito = Convert.ToInt32(T028DiasCredito.Text);
                 DataContext.SubmitChanges();
              }
              catch (System.Data.Linq.ChangeConflictException cce)
              {
                 MessageBox.Show("Error");
                 MainApp.WriteExceptionToLog(cce);
              }
              catch (SystemException se)
              {
                 MainApp.WriteExceptionToLog(se);
              }
              finally
              {
                 DataContext.Connection.Close();
              }
           }
        }

        private void RemoveRol_Click(object sender, EventArgs e)
        {
           if (currEntity != null)
           {
              if (RolesAsignado.SelectedIndex >= 0)
              {
                 var selRol = RolesAsignado.Items[RolesAsignado.SelectedIndex];
                 T013 rol = (from R in currEntity.T013s where R.T003Rol.Equals(selRol.Text) select R).SingleOrDefault();
                 if (rol != null)
                 {
                    currEntity.T013s.Remove(rol);
                    getRolesDisponibles(getRolesAsignados(currEntity));
                    DataContext.SubmitChanges();
                 }
              }
           }
        }

        private void AddRol_Click(object sender, EventArgs e)
        {
           if (currEntity != null)
           {
              if (RolesDisponible.SelectedIndex >= 0)
              {
                 var selRol = RolesDisponible.Items[RolesDisponible.SelectedIndex];
                 T013 rol = new T013();
                 rol.T003Rol = selRol.Text;
                 rol.T011Entity = currEntity.T011Entity; 
                 currEntity.T013s.Add(rol);
                 DataContext.SubmitChanges();
                 getRolesAsignados(currEntity); 
                 getRolesDisponibles(getRolesAsignados(currEntity));
                 
              }
           }
        }

        private void AddAllRoles_Click(object sender, EventArgs e)
        {
           if (RolesDisponible.Items.Count > 0 && currEntity != null)
           {
              foreach (var rolItem in RolesDisponible.Items)
              {
                 var selRol = rolItem;
                 T013 rol = new T013();
                 rol.T003Rol = selRol.Text;
                 rol.T011Entity = currEntity.T011Entity;
                 currEntity.T013s.Add(rol);
                 DataContext.SubmitChanges();
              }
           }
           getRolesAsignados(currEntity);
           getRolesDisponibles(getRolesAsignados(currEntity));
        }

        private void RemoveAllRoles_Click(object sender, EventArgs e)
        {
           if (RolesAsignado.Items.Count > 0 && currEntity != null)
           {
              foreach (var rolItem in RolesAsignado.Items)
              {
                 T013 rol = (from R in currEntity.T013s where R.T003Rol.Equals(rolItem.Text) select R).SingleOrDefault();
                 if (rol != null)
                 {
                    currEntity.T013s.Remove(rol);
                    DataContext.SubmitChanges();
                 }
              }
              getRolesAsignados(currEntity);
              getRolesDisponibles(getRolesAsignados(currEntity));
           }
        }

        private void tsbEdit_Click(object sender, EventArgs e)
        {
          
        }

        private void tsbListado_Click(object sender, EventArgs e)
        {
           CatEntityList listEntities = new CatEntityList() { MdiParent =MainApp.Wb};
           listEntities.Show();
        }
    }
}
